--
Memory Flow Setup
Overview
In a WordPress VPS running OpenLiteSpeed, “memory flow” is the layered set of limits and allocations that determine how much RAM each component can use during a request: WordPress (PHP) limits, LSAPI process limits, PHP OPcache, database buffers, optional Redis caching, and the Linux kernel’s memory and swap behavior. A single low limit in the chain can trigger “Allowed memory size exhausted” errors, while overly generous limits can cause swapping, 502/503 responses, or the Linux OOM killer terminating services.
History
- Early WordPress hosting commonly relied on a single PHP
memory_limit, with minimal isolation between PHP workers and other services. - As sites became plugin-heavy (builders, WooCommerce, backups) and concurrency increased, stacks like LSAPI/FastCGI and OPcache became standard, adding more memory layers to tune.
- VPS deployments made memory budgeting critical because web, PHP, DB, and caches share the same fixed RAM pool.
Adoption
This approach is common in:
- WordPress on VPS (single host running web server, PHP, DB)
- OpenLiteSpeed + LSAPI deployments for high-throughput PHP handling
- Sites using WooCommerce, page builders, backup plugins, and object caching
Maintainer
Maintained by the WordPress project/community, OpenLiteSpeed project, PHP project, and your OS distribution (settings span multiple components).
Best when to use
- You run WordPress on a VPS with OpenLiteSpeed and want predictable stability under load
- You need to prevent PHP worker memory spikes from starving MySQL/MariaDB
- You use OPcache and/or Redis and must budget RAM across services
- You want repeatable tuning for multiple VPS sizes (2 GB, 4 GB, 8 GB, 16 GB+)
Not suitable when
- Your database is fully managed on a separate host and you do not control DB memory settings
- You cannot change server-level configuration (shared hosting with locked PHP/LSAPI settings)
- Your traffic and workload are highly variable and require autoscaling instead of host tuning
Compatibility notes
- OpenLiteSpeed uses LSAPI for PHP workers; limits and process counts are configured in the OpenLiteSpeed WebAdmin for the
lsphpExternal App. - PHP configuration paths differ by distro and by the installed
lsphpversion. - WordPress constants (
WP_MEMORY_LIMIT,WP_MAX_MEMORY_LIMIT) can be overridden by code or hosting panels; verify effective runtime values. - Linux swap behavior differs across distros and VPS providers; excessive swapping is usually a performance failure mode.
Do not set limits based on “maximum possible.” Set them based on your VPS RAM budget and expected concurrency. Overcommitting memory often produces intermittent failures that are hard to diagnose (502/503, slow TTFB, random plugin crashes).
Memory flow hierarchy
Limits and allocations (lowest to highest)
| Layer | Setting | Location | Purpose | Typical starting point |
|---|---|---|---|---|
| -- | - | - | -- | |
| 1 | WP_MEMORY_LIMIT | wp-config.php | Memory available to WordPress frontend operations | 128M–256M |
| 2 | WP_MAX_MEMORY_LIMIT | wp-config.php | Memory for wp-admin and heavy tasks | 256M–512M |
| 3 | memory_limit | php.ini / LSWS LSAPI env | Max memory per PHP process | 512M–1024M |
| 4 | LSAPI Soft Limit | OLS WebAdmin → Server → External App → lsphp | Soft memory cap per PHP worker | 512M–1G |
| 5 | LSAPI Hard Limit | OLS WebAdmin → Server → External App → lsphp | Kill a worker exceeding this limit | 1.5G–2G |
| 6 | OPcache memory | php.ini | RAM for compiled PHP bytecode cache | 128M–512M |
| 7 | MariaDB/MySQL buffers | my.cnf | RAM used for DB caching and performance | 512M–4G+ |
| 8 | Redis maxmemory | redis.conf | RAM cap for object cache | 256M–2G (optional) |
| 9 | Linux swap | swapfile/partition | Last-resort memory pressure relief | 1–2× RAM (cap commonly 4G) |
Brotli/gzip, HTTP caching, and LiteSpeed Cache affect bandwidth and caching, but they do not replace correct RAM budgeting for PHP, DB, and Redis.
Priority flow during a request
Recommended settings by VPS size
These are conservative starting points intended to prevent swapping while supporting common WordPress workloads.
| VPS RAM | PHP memory_limit | WP_MEMORY_LIMIT | WP_MAX_MEMORY_LIMIT | OPcache | Redis maxmemory | MariaDB buffer pool |
|---|---|---|---|---|---|---|
| - | --: | -: | --: | --: | -: | : |
| 2 GB | 512M | 128M | 256M | 128M–256M | 256M (optional) | 512M |
| 4 GB | 768M | 256M | 512M | 256M–384M | 512M (optional) | 1G |
| 8 GB | 1024M | 256M | 512M–1G | 384M–512M | 1G (optional) | 2G |
| 16 GB+ | 2048M | 512M | 1G | 512M–1G | 2G (optional) | 4G+ |
Keep at least 20–30% of RAM unallocated for the OS page cache, spikes, and burst traffic. If Redis + MariaDB + PHP workers can consume nearly all RAM, the host will thrash swap or trigger the OOM killer.
Where to set each layer
WordPress (wp-config.php)
Add or adjust near the top of wp-config.php (above “stop editing” comment):
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
Some hosts or mu-plugins can override these constants. Confirm runtime values using WP-CLI (see Verification).
PHP memory_limit (OpenLiteSpeed)
Common locations:
/usr/local/lsws/lsphp*/etc/php/*/php.ini/etc/php/*/litespeed/php.ini
Example snippet in php.ini:
memory_limit = 768M
opcache.memory_consumption = 256
OpenLiteSpeed WebAdmin path:
-
Server Configuration → External App →
lsphp- Environment variables and process controls are applied here (varies by OLS version and LSAPI config layout).
LSAPI soft/hard limits (OpenLiteSpeed WebAdmin)
OpenLiteSpeed WebAdmin path (typical):
-
Server Configuration → External App →
lsphp- Memory Soft Limit
- Memory Hard Limit
- Max Connections / Children (names vary)
Changing LSAPI worker counts and memory limits can immediately affect request handling and error rates (502/503). Apply changes during a controlled window and keep a rollback plan (restore prior values and reload).
MariaDB/MySQL memory (my.cnf)
Common locations:
/etc/mysql/my.cnf/etc/mysql/mariadb.conf.d/*.cnf/etc/my.cnf
Key setting (InnoDB-heavy WordPress):
[mysqld]
innodb_buffer_pool_size = 1G
Redis memory (redis.conf)
Common location:
/etc/redis/redis.conf
Set a hard cap to prevent Redis from consuming all RAM:
maxmemory 512mb
maxmemory-policy allkeys-lru
Swap (Linux)
Swap is a safety net, not a performance feature. Use it to reduce crash risk during brief spikes, not as steady-state capacity.
Verification workflow (safe, read-only first)
Check system memory pressure
free -h
vmstat 1 5
Look for:
- Consistently low
availablememory - Swap-in/swap-out activity under normal load
- High
si/soinvmstat(swap thrashing)
Check which services are consuming RAM
ps aux --sort=-%mem | head -n 15
Check PHP and OLS listeners
sudo ss -lntp | grep -E ':(80|443)\b' || true
Confirm PHP limits
Create a temporary PHP info endpoint only if you can protect it (for example, restricted by IP and removed immediately after use). Prefer CLI checks where possible.
CLI check (path varies):
php -i | grep -E '^memory_limit|^opcache\.memory_consumption'
Do not leave a public phpinfo() page accessible on production. It reveals environment details useful to attackers.
Confirm WordPress limits (WP-CLI)
wp eval 'echo "WP_MEMORY_LIMIT=" . WP_MEMORY_LIMIT . PHP_EOL; echo "WP_MAX_MEMORY_LIMIT=" . WP_MAX_MEMORY_LIMIT . PHP_EOL;'
Sizing PHP concurrency safely
The most common stability failure on VPS is too many PHP workers combined with a high memory_limit.
Safe sizing model
- Reserve RAM for OS + DB + caches.
- Estimate per-worker PHP peak usage.
- Set max workers so peak usage does not exceed remaining RAM.
| Term | Meaning |
|---|---|
| -- | |
RAM_total | VPS total RAM |
RAM_reserved | OS + MariaDB + Redis + other daemons + headroom |
RAM_for_PHP | RAM_total - RAM_reserved |
PHP_worker_peak | realistic peak per worker (often 150–400 MB for WordPress, higher for builders/backups) |
Max_workers | floor(RAM_for_PHP / PHP_worker_peak) |
If you don’t know per-worker peak, start with 4–8 workers on 2–4 GB VPS and measure under real load. Increase gradually after confirming no swapping and stable error rates.
Common misconfiguration scenarios and impacts
The scenarios below show mismatches between layers that cause failures. Each includes typical symptoms and safe verification steps before applying fixes.
Scenario 1: Low WordPress limit but high PHP limit
| Misconfiguration | Example | Impact |
|---|---|---|
| - | ||
| WordPress caps memory below what plugins need | WP_MEMORY_LIMIT=64M, memory_limit=768M | WordPress hits “Allowed memory size exhausted” even though PHP could allow more |
Detection:
wp eval 'echo ini_get("memory_limit") . PHP_EOL;'
wp eval 'echo WP_MEMORY_LIMIT . PHP_EOL;'
Fix:
- Raise
WP_MEMORY_LIMITandWP_MAX_MEMORY_LIMITto match realistic plugin needs (within your VPS budget).
Scenario 2: WP_MAX_MEMORY_LIMIT lower than WP_MEMORY_LIMIT
| Misconfiguration | Example | Impact |
|---|---|---|
| - | -- | - |
| Admin limit is lower than frontend limit | WP_MEMORY_LIMIT=256M, WP_MAX_MEMORY_LIMIT=128M | Admin tasks fail: backups, imports, builders, cron-heavy jobs |
Fix:
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
Scenario 3: PHP memory_limit low while OPcache/Redis are high
| Misconfiguration | Example | Impact |
|---|---|---|
| - | -- | -- |
| PHP processes are constrained but caches reserve RAM | memory_limit=128M, opcache=256M, Redis maxmemory=512M | PHP fatals during normal requests; backend instability despite available cached RAM |
Detection:
php -i | grep -E '^memory_limit|^opcache\.memory_consumption'
redis-cli info memory 2>/dev/null | head -n 30 || true
Fix:
- Increase
memory_limitto a sane level (512M–1024M) and reduce cache allocations if the VPS is small.
Scenario 4: Too many PHP workers for available RAM
| Misconfiguration | Example | Impact |
|---|---|---|
| -- | ||
High worker count and high memory_limit overcommits RAM | 20 workers × 512M potential on a 4 GB VPS | 502/503 errors, swapping, OOM killer events, intermittent downtime |
Detection:
free -h
vmstat 1 5
dmesg | tail -n 100 | grep -i -E 'oom|killed process' || true
Fix:
- Reduce worker count or reduce
memory_limit. - Keep overall memory commitments under ~70–80% of RAM.
Scenario 5: OPcache too small for a plugin-heavy site
| Misconfiguration | Example | Impact |
|---|---|---|
| - | -- | |
| OPcache cannot hold compiled scripts | opcache.memory_consumption=64 | Higher CPU usage, slower TTFB, frequent recompilation |
Detection:
php -i | grep -E '^opcache\.memory_consumption|^opcache\.max_accelerated_files|^opcache\.validate_timestamps'
Fix:
- Increase OPcache memory (commonly 256–512 MB for larger sites).
- Ensure
opcache.max_accelerated_filesis sized appropriately for many PHP files.
Scenario 6: Redis enabled without maxmemory
| Misconfiguration | Example | Impact |
|---|---|---|
| - | - | -- |
| Redis grows without an upper bound | maxmemory not set | Redis consumes RAM until DB or PHP is killed; site becomes unstable or goes down |
Detection:
redis-cli config get maxmemory 2>/dev/null || true
redis-cli info memory 2>/dev/null | grep -E 'used_memory_human|maxmemory_human' || true
Fix:
- Set
maxmemoryand a sane eviction policy (commonlyallkeys-lru).
Scenario 7: MariaDB buffer pool too large for small VPS
| Misconfiguration | Example | Impact |
|---|---|---|
| -- | - | - |
| DB buffer pool consumes most RAM | innodb_buffer_pool_size=2G on 2 GB VPS | Swap thrashing, slow queries, system stalls, failures under load |
Detection:
free -h
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" 2>/dev/null || true
Fix:
- Reduce buffer pool so PHP and OS have headroom.
- Use slow query logging and indexing rather than trying to cache everything in RAM on a small VPS.
Scenario 8: No swap on a small VPS
| Misconfiguration | Example | Impact |
|---|---|---|
| - | -- | -- |
| Swap disabled | swap = 0 | Short-lived spikes can crash processes; OOM events more likely |
Detection:
swapon --show
free -h
Fix:
- Add a modest swapfile (often 1–4 GB depending on RAM and provider guidance).
- Treat swap activity as a signal to reduce memory pressure, not a steady-state strategy.
Scenario 9: PHP memory_limit higher than total RAM
| Misconfiguration | Example | Impact |
|---|---|---|
| - | -- | |
| Per-process limit exceeds realistic host capacity | memory_limit=2G on 1 GB VPS | Severe swapping or immediate OOM during heavy requests |
Fix:
- Reduce
memory_limitto a value aligned with VPS RAM and worker count.
Scenario 10: LSAPI hard limit below PHP memory_limit
| Misconfiguration | Example | Impact |
|---|---|---|
| - | - | -- |
| LSAPI kills workers before PHP can handle memory errors | LSAPI hard limit 256M, PHP memory_limit=512M | Requests fail with worker-killed errors; inconsistent behavior |
Detection:
- Check OLS error logs for “killed” or memory limit messages (path depends on your OLS log configuration).
Fix:
- Ensure LSAPI hard limit is above PHP
memory_limitwith a safety margin, or reduce PHPmemory_limitto match.
Troubleshooting checklist
Symptoms to map quickly
| Symptom | Likely layer | First checks |
|---|---|---|
| -- | -- | |
| “Allowed memory size exhausted” | WordPress constants or PHP memory_limit | WP-CLI memory values; php -i |
| 502/503 from web server | LSAPI worker limits / concurrency | worker count; swapping; OLS logs |
| Sudden DB crashes | DB memory too high or host memory pressure | dmesg OOM; DB logs; buffer pool size |
| Server becomes very slow under load | Swap thrashing / overcommit | vmstat, free -h, disk I/O |
| High CPU with normal traffic | OPcache too small or disabled | OPcache settings and stats |
Safe commands before changing settings
free -h
vmstat 1 5
ps aux --sort=-%mem | head -n 15
dmesg | tail -n 100 | grep -i -E 'oom|killed process' || true
Quick reference
Key settings and locations
| Setting | Location |
|---|---|
| - | |
WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT | wp-config.php |
PHP memory_limit, OPcache settings | php.ini (lsphp path varies by distro/version) |
| LSAPI soft/hard limits, worker settings | OLS WebAdmin → Server Configuration → External App → lsphp |
| MariaDB memory | my.cnf / mariadb.conf.d |
| Redis memory cap | redis.conf |
| Swap | swapfile/partition and system config |
Safe starting values (common)
| Component | Conservative starting point |
|---|---|
| WordPress frontend | WP_MEMORY_LIMIT=256M |
| WordPress admin | WP_MAX_MEMORY_LIMIT=512M |
| PHP | memory_limit=768M (4 GB VPS baseline) |
| OPcache | opcache.memory_consumption=256 |
| Redis | maxmemory=512mb (optional) |
| MariaDB | innodb_buffer_pool_size=1G (4 GB VPS baseline) |
WP_MEMORY_LIMIT and WP_MAX_MEMORY_LIMIT control WordPress’s own memory ceiling, but PHP’s memory_limit still applies as the hard cap for the PHP process. Both must be aligned, with PHP typically equal to or higher than WordPress limits.